package Model;

/**
 * Classe responsavel por gerar o tiles utilizados na IA dos zumbis.
 * Nesta classe o algoritmo utilizado na IA identifica o custo do caminho tomado bem como o tile inicial
 * e o tile final.
 * 
 * @author Edjane Catolle, Igor Henrique, Luiz Augusto, Vladmir Chicarolli
 * @version 1.0.0
 * @since 06/05/2011
 */

import java.awt.Rectangle;
import java.util.HashSet;
import java.util.Set;


public class MapTile 
{
	private Rectangle mRectangle;
	private int x;
	private int y;
	private boolean start;
	private boolean isSheeps;
	private int value;
	
	private double localCost; // custo do no atual ao objetivo
	private double parentCost; // custo do no pai para o no atual
	
	private Map map;
	private Set<MapTile> neighbors = new HashSet<MapTile>();
	private MapTile parent;

	public MapTile(Rectangle mRectangle, Map map, int value)
	{
		this.mRectangle = mRectangle;
		x = mRectangle.x / 50;
		y = mRectangle.y / 50;
		this.map = map;
		this.value = value;
	}
	
	public int GetValue()
	{
		return value;
	}
	
	/**
	 * O no analisado eh o inicial
	 * @return - TRUE se o no analisado eh o no inicial
	 */
	public boolean isStart() 
	{
		return start;
	}

	/**
	 * Configura o tile como inicio
	 * @param start - TRUE se o tile for o inicio
	 */
	public void setStart(boolean start) 
	{
		this.start = start;
	}

	/**
	 * O tile analisado eh o tile com as ovelhas
	 * @return - TRUE se o tile for as ovelhas
	 */
	public boolean IsSheeps()
	{
		return isSheeps;
	}

	/**
	 * Configura o tile onde estao as ovelhas
	 */
	public void SetIsSheeps()
	{
		this.isSheeps = true;
	}
	
	public Rectangle GetTileRect()
	{
		return mRectangle;
	}
	
	/**
	 * Insere os vizinhos do tile na lista de vizinhos
	 * @param mt - tile a ser inserido na lista.
	 */
	public void addNeighbor(MapTile mt)
	{
		neighbors.add(mt);
	}
	
	/**
	 * Vizinhos do tile analisado
	 * @return - retorna uma lista com os vizinhos do tile analisado.
	 */
	public Set<MapTile> getNeighbors() 
	{
		return neighbors;
	}

	public MapTile getParent() 
	{
		return parent;
	}

	public void setParent(MapTile mt) 
	{
		this.parent = mt;
	}
	
	public double getPass(MapTile sheeps)
	{
		if(isStart())
		{
			return 0.0;
		}
		
		return GetLocalCost(sheeps) + GetParentCost();
	}
	
	public double GetLocalCost(MapTile sheeps)
	{
		if(isStart())
		{
			return 0.0;
		}
		
		localCost = 1.0 * (Math.abs(x - sheeps.x) + Math.abs(y - sheeps.y));
		return localCost;
	}
	
	public double GetParentCost()
	{
		if(isStart())
		{
			return 0.0;
		}
				
		if(parentCost == 0.0)
		{
			parentCost = 1.0 + .5 * (parent.GetParentCost() - 1.0);
		}
		
		return parentCost;
	}
	
	public void CalculateNeighbor()
	{
		int bottom = x + 1;
		int right = y + 1;
		
		if (bottom < map.GetRows()) 
		{			
			if (isAdjacent()) 
			{
				map.GetTileByCordinates(bottom, y).addNeighbor(this);
				this.addNeighbor(map.GetTileByCordinates(bottom, y));				
			}
		}

		if (right < map.GetCollumns()) 
		{			
			if (isAdjacent()) 
			{
				map.GetTileByCordinates(x, right).addNeighbor(this);
				this.addNeighbor(map.GetTileByCordinates(x, right));				
			}
		}
	}
	
	public boolean isAdjacent(MapTile mt) 
	{		
		if(mt.value != 0)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	
	public boolean isAdjacent() 
	{		
		if(this.value != 0)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
}
